package com.train.mgr.modules.biz.controller;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.NumberUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson2.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.google.gson.JsonObject;
import com.train.common.exception.BizException;
import com.train.common.exception.BusinessException;
import com.train.common.model.PageResult;
import com.train.common.model.R;
import com.train.common.utils.AuthUtils;
import com.train.mgr.config.redis.RedisUtil;
import com.train.mgr.modules.biz.dto.TraineeCourseDetailVo;
import com.train.mgr.modules.biz.dto.TraineeCourseVo;
import com.train.mgr.modules.biz.dto.request.*;
import com.train.mgr.modules.biz.dto.response.*;
import com.train.mgr.modules.biz.entity.Course;
import com.train.mgr.modules.biz.entity.CourseStuGroup;
import com.train.mgr.modules.biz.entity.CourseStuGroupRel;
import com.train.mgr.modules.biz.entity.LessonUserExercise;
import com.train.mgr.modules.biz.service.*;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;


@Slf4j
@RequiredArgsConstructor
@RestController
@Api( tags = "学员端接口")
@RequestMapping("/v1/trainee")
public class TraineeController {

    private final ICourseUserService courseUserService;
    private final ICourseService courseService;
    private final ITraineeService traineeService;
    private final ICourseStuGroupService courseStuGroupService;
    private final ICourseStuGroupRelService courseStuGroupRelService;
    private final ILessonUserExerciseService lessonUserExerciseService;
    private final RedisUtil redisUtil;
    @GetMapping("/coursePage")
    @ApiOperation("我的课程")
    public R<PageResult<TraineeCourseDetailVo>> coursePage(TraineeCoursePageDTO req) {
        PageResult<TraineeCourseDetailVo> pageResult = courseUserService.getMyCourse(req);
        return R.succeed(pageResult);
    }

    @GetMapping("/joinCourse/{courseCode}")
    @ApiOperation("加入课程")
    public R<TraineeCourseVo> joinCourse(@PathVariable(name = "courseCode") String courseCode) {
        Course course = courseService.selectCourceByCourceCode(courseCode, AuthUtils.getCurrentUser().getCustomerId());
        if (course ==null){
            throw new BizException("找不到该课程，请检查课程码是否正确！");
        } else {
            Date deadline = course.getDeadline();
            if (deadline != null && DateUtil.date().after(deadline)){
                throw new BizException("该课程已截止，不能加入学习！");
            }
        }
        TraineeCourseVo vo = new TraineeCourseVo(course.getId(),course.getCourseName(),course.getDeadline());
        return R.succeed(vo);
    }

    @GetMapping("/getCourse/{courseId}")
    @ApiOperation("课程主页")
    public R<TraineeCourseHomeDTO> getCourse(@PathVariable(name = "courseId") Long courseId) {
        TraineeCourseHomeDTO courseHome = traineeService.getCourseHome(courseId);
        return R.succeed(courseHome);
    }

    @GetMapping("/joinHomeCourse/{courseId}")
    @ApiOperation("课程主页-加入课程")
    public R<JoinCourseDTO> joinHomeCourse(@PathVariable(name = "courseId") Long courseId) {
        JoinCourseDTO dto = traineeService.joinHomeCourse(courseId);
        return R.succeed(dto);
    }

    @GetMapping("/onStudy")
    @ApiOperation("课程主页-进入学习")
    public R<TraineeOnStudyReqpDTO> onStudy(TraineeLessionListReqDTO req) {
        TraineeOnStudyReqpDTO dto = traineeService.onStudy(req);
        return R.succeed(dto);
    }

    @GetMapping("/getExercise/{courseId}")
    @ApiOperation("课程主页-练习记录")
    public R<List<TraineeExerciseDTO>> getExercise(@PathVariable(name = "courseId") Long courseId) {
        List<TraineeExerciseDTO> courseHome = traineeService.getCourseHomeExercise(courseId);
        return R.succeed(courseHome);
    }

    @GetMapping("/getAllExercise")
    @ApiOperation("课程主页-练习记录-更多 (与【我的练习-分页接口】同一个接口)")
    public R<PageResult<TraineeAllExerciseDTO>> getAllExercise(TraineeExercisePageDTO dto) {
        PageResult<TraineeAllExerciseDTO> pageResult = traineeService.getAllExercise(dto);
        return R.succeed(pageResult);
    }


//    @GetMapping("/getReview/{courseId}")
//    @ApiOperation("课程主页-复习提醒(P2再完善)")
//    public R<List<TraineeExerciseDTO>> getReview(@PathVariable(name = "courseId") Long courseId) {
//        List<TraineeExerciseDTO> courseHome = traineeService.getCourseHomeExercise(courseId);
//        return R.succeed(courseHome);
//    }
////

    @GetMapping("/exercise/getReport/{exerciseId}")
    @ApiOperation("我的练习-查看报告")
    public R<TraineeStudyExerciseRespDTO> getReport(@PathVariable(name = "exerciseId") Long exerciseId) {
        TraineeStudyExerciseRespDTO dto = traineeService.getReport(exerciseId);
        return R.succeed(dto);
    }

    @GetMapping("/exercise/getReportState/{exerciseId}")
    @ApiOperation("查看报告生成状态")
    public R<String> getReportState(@PathVariable(name = "exerciseId") Long exerciseId) {
        Object o = redisUtil.get("report:" + exerciseId);
        log.info("exerciseId:{},查看报告生成状态：{}",exerciseId,o);
        if(ObjectUtil.isEmpty(o)){
            LessonUserExercise dto = lessonUserExerciseService.getById(exerciseId);
            return R.succeed(dto.getIsGenerateReports()+"","报告生成状态");
        }
        return R.succeed(o.toString(),"报告生成状态");
    }

    @GetMapping("/exercise/getSearch")
    @ApiOperation("我的练习-获取检索下拉框")
    public R<List<TraineeStudyExerciseSearchRespDTO>> getSearch() {
        List<TraineeStudyExerciseSearchRespDTO> dto = traineeService.getSearch();
        return R.succeed(dto);
    }

    @PostMapping("/study/courseList")
    @ApiOperation("学习详情-课程表")
    public R<TraineeLessionListRespDTO> courseList(@RequestBody TraineeLessionListReqDTO req) {
        TraineeLessionListRespDTO dto = traineeService.getLessionListByCourseId(req);
        return R.succeed(dto);
    }

    @PostMapping("/study/switchLesson")
    @ApiOperation("学习详情-课程表-切换课时")
    public R<TraineeOnStudyReqpDTO> switchLesson(@RequestBody TraineeLessionListReqDTO req) {
        TraineeOnStudyReqpDTO dto = traineeService.switchLesson(req);
        return R.succeed(dto);
    }

    @PostMapping("/study/report")
    @ApiOperation("学习详情-更多报告")
    public R<TraineeStudyExerciseRespDTO> report(@RequestBody TraineeProjectReportReqDTO req) {
        TraineeStudyExerciseRespDTO dto = traineeService.getProjectReport(req);
        return R.succeed(dto);
    }

    @PostMapping("/exercise/save")
    @ApiOperation("保存练习")
    public R<String> add(@RequestBody @Validated LessonUserExerciseReqDTO body) {
        log.info("保存练习入参:{}", JSONObject.toJSONString(body));
        String useTime = body.getUseTime();
        if (StrUtil.isBlank(useTime) || new BigDecimal(useTime).compareTo(BigDecimal.ZERO) == 0){
            throw new BizException("学习时长不能为0！");
        }
        String result = traineeService.saveExercise(body);
        return R.succeed(result);
    }

    @PostMapping("/exercise/update")
    @ApiOperation("更新练习（更新报告分数）")
    public R<Boolean> update(@RequestBody @Validated LessonUserExerciseReqDTO body) {
        Boolean result = traineeService.updateExercise(body);
        return R.succeed(result);
    }

    @GetMapping("/getGroup/{courseId}")
    @ApiOperation("获取分组列表")
    public R<List<GroupRespListDTO>> getGroup(@PathVariable(name = "courseId") Long courseId) {
        LambdaQueryWrapper<CourseStuGroup> w = new LambdaQueryWrapper<>();
        w.eq(CourseStuGroup::getCourseId,courseId)
                .eq(CourseStuGroup::getCustomerId,AuthUtils.getCurrentUser().getCustomerId())
                .eq(CourseStuGroup::getIsDeleted,0);
        List<CourseStuGroup> list = courseStuGroupService.list(w);
        List<GroupRespListDTO> dtos = list.stream().map(item -> {
            GroupRespListDTO dto = new GroupRespListDTO();
            BeanUtils.copyProperties(item,dto);
            return dto;
        }).collect(Collectors.toList());
        return R.succeed(dtos);
    }


    @PostMapping("/bindGroup")
    @ApiOperation("绑定分组")
    public R<Boolean> bindGroup(@RequestBody @Validated TraineeCourseUserGroupReqDTO req) {
        CourseStuGroup group = courseStuGroupService.getById(req.getGroupId());
        if (group == null){
            throw new BusinessException("分组不存在");
        }
        Long courseId = new Long(req.getCourseId());
        Course course = courseService.getById(courseId);
        if (course == null){
            throw new BusinessException("课程不存在");
        }
        CourseStuGroupRel rel = new CourseStuGroupRel();
        rel.setGroupId(req.getGroupId());
        rel.setCourseId(course.getId());
        rel.setUserId(AuthUtils.getCurrentUser().getId());
        return R.succeed(courseStuGroupRelService.save(rel));
    }

    @GetMapping("/getTrainee")
    @ApiOperation("我的")
    public R<TraineeStuRespDTO> getTrainee() {
        TraineeStuRespDTO dto = traineeService.getTrainee();
        return R.succeed(dto);
    }

}
